<!-- https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer
    "https://wl.arcgisonline.cn/server/rest/services/wl/hightf/FeatureServer/0",
-->




<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>SceneView - goTo() | Sample | ArcGIS API for JavaScript 4.20</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.20/esri/themes/light/main.css" />
  <script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
  <script src="https://js.arcgis.com/4.20/"></script>
  <style>
    html,
    body,
    #mapView {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #btns {
      position: absolute;
      bottom: 10px;
      width: 100%;
      z-index: 1;
      text-align: center;
      cursor: pointer;
    }

    #toPoint {
      background: white;
      padding: 10px;
      border: 1px solid blue;
      color: blue;
    }

    #toPoint:hover {
      background: blue;
      color: white;
    }

    #showHeatMap,
    #removeHeatMap {
      padding: 10px;
      border: 1px solid red;
      color: red;
    }

    #showHeatMap:hover,
    #removeHeatMap:hover {
      background: red;
      color: white;
    }

    #setPoints {
      background: white;
      padding: 10px;
      border: 1px solid green;
      color: green;
    }

    #setPoints:hover {
      background: green;
      color: white;
    }
  </style>

  <script>
    require(
      [
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/TileLayer",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/core/promiseUtils",
        "esri/Graphic",
        "esri/geometry/Point",
        "esri/rest/locator",
        "dojo/_base/lang",
      ], (
        Map,
        SceneView,
        TileLayer,
        MapView,
        FeatureLayer,
        promiseUtils,
        Graphic,
        Point,
        locator,
        lang
      ) => {
      const map = new Map();
      const view = new SceneView({
        container: "mapView",
        map: map,
        zoom: 4
      });

      let dTlayer = new TileLayer({
        // url: "https://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer"
        url: "https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer",
      });
      map.add(dTlayer);

      let lineList = []
      view.on("click", e => {
        let { mapPoint: { longitude: x, latitude: y } } = e;
        lineList.push([x, y, parseInt(Math.random() * 100)]);
        console.log(JSON.stringify(lineList));
        view.hitTest(e).then(event => {
          console.log(event);
        });
      })

      view.when(() => {
        // 地图加载完成
        setTimeout(() => {
          view.goTo({
            position: {
              x: 121.42989101233015,
              y: 31.221434715924108,
              z: 100000,
              spatialReference: {
                wkid: 4326
              }
            },
            heading: 0,
            tilt: 0,
          },
            {
              duration: 3000,
              easing: 'linear'
            }
            // 蹦跶几下？
            /**
             *  // Define your own function for the easing option
             *      function customEasing(t) {
             *         return 1 - Math.abs(Math.sin(-1.7 + t * 4.5 * Math.PI)) * Math.pow(0.5, t * 10);
             *      }
             */
            // {
            //     speedFactor: 0.3,
            //     easing: customEasing
            // }
          ).catch(catchError);
        }, 500);
      })
        .then(mapInitFinish).catch(catchError);

      // 地图初始化完成
      function mapInitFinish() {

      }


      function heatMap() {
        class HeatLayer {
          constructor(obj) {
            let { lang, Point } = obj;
            this.view = view;
            this.lang = lang;
            this.Point = Point;
            //配置热力图的颜色、半径
            this.config = {
              radius: 20,
              gradient: {
                0.5: 'rgba(0,0, 255)',
                0.65: 'rgb(117,211,248)',
                0.7: 'rgb(0, 255, 0)',
                0.9: '#ffea00',
                1.0: 'rgb(255, 50, 0)'

                // 0:"rgba(250, 0, 0, 0)",
                // 0.5:"rgb(250, 0, 0)" ,
                // 0.7: "rgb(250, 150, 0)",
                // 0.9: "rgb(255, 255, 0)"
              }
            };
            this.canvas = null;
            this.context = null;
            this.minnum = 1;
            this.maxnum = 1;
            this.visible = true;
            // this.spatialReference = { wkid: 102100 };
            this.spatialReference = { wkid: 4326 };
            this.createCanvas();
          }
          /*创建Canvaslayer的容器canvas，添加到map的layers下面*/
          createCanvas() {
            let canvas = document.createElement("canvas");
            canvas.width = this.view.width;
            canvas.height = this.view.height;
            canvas.setAttribute("id", "heatmap");
            canvas.style.position = "absolute";
            canvas.style.top = 0;
            canvas.style.left = 0;
            let parent = document.getElementsByClassName(
              "esri-view-surface"
            )[0];
            parent.appendChild(canvas);
            this.canvas = canvas;
            this.context = document
              .getElementById("heatmap")
              .getContext("2d");
            this.startMapEventListeners();
          }
          /*转换数据*/
          convertHeatmapData(data) {
            var heatPluginData = [];
            for (let i = 0; i < data.length; i++) {
              let screenpoint = this.view.toScreen(
                new this.Point({
                  // longitude: data[i][0],
                  // latitude: data[i][1],
                  x: data[i][0],
                  y: data[i][1],
                  spatialReference: this.spatialReference
                })
              );
              // 判断数据是否带有权重，未带有权重属性是默认为1
              if (data[0].length == 3) {
                heatPluginData.push([
                  Math.round(screenpoint.x),
                  Math.round(screenpoint.y),
                  data[i][2]
                ]);
              } else {
                heatPluginData.push([
                  Math.round(screenpoint.x),
                  Math.round(screenpoint.y),
                  1
                ]);
              }
              if (this.minnum > data[i][2]) {
                this.minnum = data[i][2];
              }
              if (this.maxnum < data[i][2]) {
                this.maxnum = data[i][2];
              }
            }
            return {
              points: heatPluginData,
              min: this.minnum,
              max: this.maxnum
            };
          }
          //添加点数据
          addPoint(data) {
            this.data = data;
            let points = this.convertHeatmapData(data);
            //console.log(points)
            points.points.forEach(point => {
              this.context.beginPath();
              let alpha = (point[2] - points.min) / (points.max - points.min);
              this.context.globalAlpha = alpha;
              this.context.arc(
                point[0],
                point[1],
                this.config.radius,
                0,
                Math.PI * 2,
                true
              );
              //绘制一个放射渐变样式的圆
              let gradient = this.context.createRadialGradient(
                point[0],
                point[1],
                0,
                point[0],
                point[1],
                this.config.radius
              );
              gradient.addColorStop(0, "rgba(0,0,0,1)");
              gradient.addColorStop(1, "rgba(0,0,0,0)");
              this.context.fillStyle = gradient;
              this.context.closePath();
              this.context.fill();
            });
            this.MapColors();
            //console.log('haol')
          }
          //设置渐变色带
          getColorPaint() {
            let paletteCanvas = document.createElement("canvas");
            let paletteCtx = paletteCanvas.getContext("2d");
            let gradientConfig = this.config.gradient;
            paletteCanvas.width = 256;
            paletteCanvas.height = 1;
            let gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
            for (let key in gradientConfig) {
              gradient.addColorStop(key, gradientConfig[key]);
            }
            paletteCtx.fillStyle = gradient;
            paletteCtx.fillRect(0, 0, 256, 1);
            return paletteCtx.getImageData(0, 0, 256, 1).data;
          }
          //映射颜色
          MapColors() {
            let palette = this.getColorPaint();
            let img = this.context.getImageData(
              0,
              0,
              this.canvas.width,
              this.canvas.height
            );
            let imgData = img.data;
            for (let i = 0; i < imgData.length; i++) {
              let alpha = imgData[i];
              let offset = alpha * 4;
              if (!offset) {
                continue;
              }
              //映射颜色RGB值
              imgData[i - 3] = palette[offset];
              imgData[i - 2] = palette[offset + 1];
              imgData[i - 1] = palette[offset + 2];
            }
            this.context.putImageData(
              img,
              0,
              0,
              0,
              0,
              this.canvas.width,
              this.canvas.height
            );
          }
          /*刷新layer*/
          freshenLayer() {
            this.clearCanvas();
            this.addPoint(this.data);
          }
          /*清除渲染效果*/
          clearCanvas() {
            this.context.clearRect(0, 0, this.view.width, this.view.height);
          }
          removeCanvas() {
            this.clearCanvas()
            document.getElementById("heatmap") && document.getElementById("heatmap").remove();
          }
          /*添加监听*/
          startMapEventListeners() {
            let view = this.view;
            view.watch(
              "extent",
              this.lang.hitch(this, () => {
                if (!this.visible) return;
                this.freshenLayer();
                console.log('监听到移动了');
              })
            );
            view.watch(
              "camera",
              this.lang.hitch(this, () => {
                if (!this.visible) return;
                this.freshenLayer();
                console.log("监听到缩放了");
              })
            );
          }
        }
        var heatmap = new HeatLayer({
          lang,
          Point
        });
        let heatPoints = [[121.46638298884814,31.250357600026337,53],[121.47011405800387,31.25863735310445,11],[121.48502571952145,31.26946406249685,33],[121.49547213562428,31.279656626160865,48],[121.49696828599401,31.283480277520642,7],[121.50369099003768,31.292402015073304,0],[121.51936142941179,31.29940785648915,77],[121.52682650847804,31.30322967937753,45],[121.53354430943503,31.30577645020285,76],[121.54622550100314,31.30640547804193,3],[121.56412731085638,31.306391039147073,52],[121.58649543505615,31.303180533278162,24],[121.59243413768023,31.29488374003492,61],[121.60208293789444,31.28212085315055,23],[121.60722257098419,31.26108160272421,94],[121.60792658048233,31.25024927475843,76],[121.60934341630772,31.231139284220603,10],[121.60555929608745,31.21522707470839,40],[121.60240074818788,31.160511606406025,55],[121.60237447098093,31.152244291221233,14],[121.59788488096311,31.14334866580241,16],[121.59263626612154,31.12873411753196,26],[121.58889728960065,31.121111894404763,17],[121.58662726944966,31.107133836145024,82],[121.58362820976544,31.097607183186952,96],[121.57913252523913,31.083637542229656,4],[121.57686666059743,31.06966796555758,17],[121.56568559597827,31.051903915242377,36],[121.55081088527017,31.035410292210404,30],[121.53298661033448,31.024636437346995,87],[121.4581886644057,31.24653843402052,40],[121.44031817065967,31.25354762765381,12],[121.45223502369791,31.254182715558024,80],[121.43287025803922,31.25418521229008,7],[121.4276564167185,31.25737039058575,20],[121.4135033540272,31.25864391836937,39],[121.4045644594343,31.258642781735904,38],[121.3963703666188,31.258641196372825,47],[121.38668571883174,31.259275716539847,14],[121.37476652213171,31.259271594536617,41],[121.35465445041773,31.257987995130314,17],[121.3412499044715,31.25543172459771,8],[121.32264389755925,31.247774284521334,88],[121.31076225461047,31.233753481370254,23],[121.30486494709619,31.211466910148964,56],[121.3205862267189,31.166948409733024,86],[121.33250298353026,31.156148145529045,67],[121.34367351489931,31.14407683733544,45],[121.35335892615481,31.127557140288474,25],[121.36824353784435,31.10596143871371,48],[121.37939234649545,31.097073342310622,22],[121.39202352605267,31.086280888454016,99],[121.40464974145151,31.07485424374463,0],[121.41059011959157,31.06787136545799,70],[121.42172332907627,31.060255216351933,96],[121.43582077616917,31.051369125795144,42],[121.44398018541887,31.045019127012857,20],[121.4669700931223,31.03422197132943,55],[121.48550882163836,31.027859760588175,20],[121.49663222318827,31.02531097809324,71],[121.50915847092016,31.022421703843403,20],[121.46412987445379,31.039251375017464,76],[121.44651546132863,31.05256704255469,88],[121.41903412250645,31.080960932457405,3],[121.94289439467991,30.91856685315386,94],[121.94100917283876,30.932023785257698,8],[121.94605796645597,30.92760714563943,50],[121.93861017764202,30.93160565623738,62],[121.92859719582943,30.935805422981776,30],[121.91042528403287,30.941806341239968,83],[121.90343360146636,30.942807193903064,13],[121.9266378010878,30.93155786858729,69],[121.92819785048972,30.933427873141415,31],[121.93677460233285,30.937835193543112,3],[121.91713691821845,30.93663806156724,7],[121.91728633752835,30.924215107418956,26],[121.9300539232944,30.922209051038646,14],[121.92797684206116,30.941085118580684,52],[121.90633937219621,30.94354113705742,92],[121.92021508039817,30.930933694662745,54],[121.93571493527227,30.920079041839465,11],[121.93080238863138,30.898742948009144,6],[121.9312176240876,30.908535412693045,25],[121.9446722895927,30.903283509022298,68],[121.93405190903961,30.88300880270456,86],[121.91163499993532,30.891405677606663,84],[121.87085942209993,30.896999565245867,68],[121.87532126068645,30.928136539916554,53],[121.85939748740508,30.933034826810758,82],[121.86224892109534,30.938287402009102,58],[121.88429852968181,30.931287621207897,92],[121.86840905481913,30.90119564411609,87],[121.86720547396462,30.87881985740462,20],[121.89044044199854,30.871834223520008,79],[121.8957382513708,30.870436847670693,79],[121.89859187917386,30.85716243780048,7],[121.88718596261786,30.85716165727914,31],[121.86559002332544,30.86274629107768,8],[121.8460178003684,30.87287197178028,19],[121.8423139735702,30.89629178132405,56],[121.85081977837517,30.93653388380577,58],[121.86962575933704,30.90854065333785,77],[121.83780923018571,30.907131906296744,67],[121.8381807243437,30.927077105161636,17],[121.82660080526144,30.995415485197363,87],[121.78800045672656,30.91481623190084,99],[121.78031660441552,30.89277596928075,23],[121.83824595831943,30.882682363682733,90]]
        heatmap.addPoint(heatPoints);
        heatmap.freshenLayer();//添加热力之后刷新一次 去掉模糊点
        // 删除热力图
        document.getElementById("removeHeatMap").addEventListener("click", () => {
          heatmap.removeCanvas();
        });
      }


      function createPoints() {
        let pointInfos = [
          { id: '001', name: "是小枫枫呀", points: [121.42475165545727, 31.22490863769794], url: 'http://www.linfengya.cn/content/uploadfile/202005/thum-e1681588918254.jpg' },
          { id: '002', name: "是小枫枫呀", points: [121.47274893053799, 31.258316787058238], url: 'http://www.linfengya.cn/content/uploadfile/202005/thum-e1681588918254.jpg' },
          { id: '003', name: "是小枫枫呀", points: [121.52686113969887, 31.22487325358598], url: 'http://www.linfengya.cn/content/uploadfile/202005/thum-e1681588918254.jpg' },
          { id: '004', name: "是小枫枫呀", points: [121.49869796631062, 31.17919912642843], url: 'http://www.linfengya.cn/content/uploadfile/202005/thum-e1681588918254.jpg' },
          { id: '005', name: "是小枫枫呀", points: [121.44118745147222, 31.180389482438905], url: 'http://www.linfengya.cn/content/uploadfile/202005/thum-e1681588918254.jpg' }
        ]

        let graphics = pointInfos.map(item => {
          // let { }  = item
          // const simpleLineSymbol = {
          //   type: "simple-line",
          //   color: [226, 119, 40], // Orange
          //   width: 2
          // };
          return new Graphic({
            geometry: new Point({
              x: item.points[0],
              y: item.points[1],
              spatialReference: {
                wkid: 4326
              }
            }),
            attributes: {
              OBJECTID: item.id,
              x: item.points[0],
              y: item.points[1],
              spatialReference: {
                wkid: 4326
              },
              ...item
            },

          })
        })
        let myPointLayer = new FeatureLayer({
          source: graphics,
          objectIdField: "OBJECTID",
          // 放入参数
          fields: [{
            name: "OBJECTID",
            type: "oid"
          }, {
            name: "url",
            type: "string"
          }, {
            name: "name",
            type: "string"
          }],
          popupTemplate: {
            title: (event) => {
              return "枫枫不疯"
            },
            content: `
            <div> 
              <img src='{url}'>
              <p> 
                <a style="font-size:28px;color:red;" href="http://www.linfengya.cn/">去找{name}，走你biubiu~</a> 
              </p> 
            </div>
            `
          },
          // renderer: {
          //   type: "simple",
          //   symbol: {
          //     type: "simple-marker",
          //     size: 10,
          //     color: "red",
          //     outline: {
          //       width: 0.5,
          //       color: "black"
          //     }
          //   }
          // }

          renderer: {
            type: "unique-value",
            defaultSymbol: {
              // 类型有 图片标记 和 点
              type: "picture-marker",
              // 图片地址
              // url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
              // url:"https://www.arcgis.com/sharing/rest/community/groups/1d1f24e8556642f49448f1c88b5a571b/info/Esri_Logo_13.jpg",
              url: "https://webapps-cdn.esri.com/CDN/country-flags/cn.png",
              // 图片的大小
              width: "60px",
              height: "60px"
            }
          }
        });
        map.add(myPointLayer)
      }

      function catchError(error) {
        console.error(error);
      }
      document.getElementById("toPoint").addEventListener("click", () => {
        view.goTo({
          position: {
            x: 121.49968765017447,
            y: 31.240005779890133,
            z: 3000,
            spatialReference: {
              wkid: 4326
              // wkid: 102100
            }
          },
          heading: 0,
          tilt: 0
        },
          {
            duration: 1000,
            easing: "linear"//"linear"|"in-cubic"|"out-cubic"|"in-out-cubic"|"in-expo"|"out-expo"|"in-out-expo"|"in-out-coast-quadratic"
          }
        ).catch(catchError);
      });
      document.getElementById("showHeatMap").addEventListener("click", () => {
        heatMap();
      });
      document.getElementById("setPoints").addEventListener("click", () => {
        createPoints();
      });
    });
  </script>
</head>

<body>
  <div id="btns">
    <button id="toPoint">to东方明珠</button>
    <button id="showHeatMap">显示热力图</button>
    <button id="removeHeatMap">移除热力图</button>
    <button id="setPoints">地图撒点</button>
  </div>
  <div id="mapView"></div>
</body>

</html>